/**
 * RegistrationImpl.java
 * 
 * @author Beatrice Bacelli
 * @author Luca Bedogni
 * @author Silvia Righini
 */
package unibo.lsb.communication;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import unibo.lsb.exception.TokioException;
import unibo.lsb.logic.PlayerId;
import unibo.lsb.logic.PlayerSelfSingleton;
import unibo.lsb.server.ConfigurationConstants;
import unibo.lsb.server.Game;
import unibo.lsb.server.RegistrationServer;

/**
 * 
 */
public class RegistrationImpl implements Registration {

	RegistrationServer rs;

	public RegistrationImpl(String serverAddr) throws TokioException {
		try {
			// Connect to RMI at serverAddr:1099
			String objectURL = "rmi://" + serverAddr + ":"
					+ ConfigurationConstants.RMIREGISTRYPORT + "/"
					+ ConfigurationConstants.REGISTRATIONSERVER_NAME;
			rs = (RegistrationServer) Naming.lookup(objectURL);

		} catch (MalformedURLException e) {
			e.printStackTrace();
			throw new TokioException("Bad url", "R01: URL Error");
		} catch (RemoteException e) {
			e.printStackTrace();
			throw new TokioException("Error connecting", "R02: ConnectionError");
		} catch (NotBoundException e) {
			e.printStackTrace();
			throw new TokioException("Error connecting", "R03: ConnectionError");
		}
		if (rs == null) {
			System.err.println("Error: RegistrationServer is null");
			throw new TokioException("Error connecting", "R04: ConnectionError");
		}
	}

	public List<Game> connectToServer() throws TokioException {
		// throw new UnsupportedOperationException("Not supported yet.");
		List<Game> ls = null;
		try {
			ls = rs.getGameList();
		} catch (Exception e) {
			e.printStackTrace();
			throw new TokioException("Error connecting",
					"R05: Connection error");
		}
		return ls;
	}

	public boolean chooseGame(String gameName, String username, String password)
			throws TokioException {
		int port = ConfigurationConstants.RMIREGISTRYPORTINFORMATION;
		PlayerId self = null;
		boolean b = false;
		try {

			port = ConnectionUtils
					.launchRMIRegistry(ConfigurationConstants.RMIREGISTRYPORTINFORMATION);
			ConnectionUtils.bindService(new CommunicationRemoteImpl(),
					ConfigurationConstants.SERVER_IP, port,
					ConfigurationConstants.INFORMATIONSERVER_NAME);
			self = rs.joinGame(gameName, username, password, port);
			if (self == null) {

				throw new TokioException("Error",
						"R06: Connection error - self NULL");

			} else {
				PlayerSelfSingleton pss = PlayerSelfSingleton.getInstance();
				pss.setPlayerId(self);

				/*
				 * after the player registers to game and receives its PlayerId
				 * from the server, it confirms its participation. Last confirm
				 * starts the game.
				 */

				rs.confirm(gameName);

				b = true;
			}
		} catch (RemoteException ex) {
			Logger.getLogger(RegistrationImpl.class.getName()).log(
					Level.SEVERE, null, ex);
		} catch (MalformedURLException ex) {
			Logger.getLogger(RegistrationImpl.class.getName()).log(
					Level.SEVERE, null, ex);
		} catch (Exception e) {
			e.printStackTrace();
			throw new TokioException("Error", "R07: Connection error");
		}

		return b;
	}

	@Override
	public boolean createGameOnServer(String gameName, int players)
			throws TokioException {
		boolean b = false;
		try {
			b = rs.createGame(gameName, players);
		} catch (Exception e) {
			e.printStackTrace();
			throw new TokioException("Error", "R08: Connection error");
		}
		return b;
	}

}
